package de.wittekind.bundesjugendspiele.client.management.model;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

interface TreeIterator extends Iterator<Tree> {
	public TreeIterator up = null;
	boolean hasNextLower();
	Tree nextLower();
	int children();
}

public class Tree {
	
	protected Tree parent;
	protected Set<Tree> children;
	Object content;
	
	public Tree( Object content ) {
		this.content = content;
		children = new HashSet<Tree>();
	}
	
	public Object getContent() {
		return content;
	}
	
	public Tree getChild( Object obj ) {
		for ( Tree t : children ) {
			
			if ( (t.getContent() == null && obj != null) )  return null;
			else {
				if ( t.getContent() == null) return t;
				else if(t.getContent().equals(obj)) return t;
			}
		}
		return null;
	}
	
	public int getChldrenAmount () {
		return children.size();
	}

	public void addChild( Object content ) {
		Tree t = new Tree (content);
		t.parent = this;
		this.children.add(t);
	}
	
	
	@Override
	public String toString() {
		String s = content != null ? content.toString() : "null";
		String indent = new String();

		for (Tree t : children){
			s = s.concat(t.toString());
			s = s.concat(indent);
		}
		return s + "\n";
	}
	
	public TreeIterator iterator () {
		return iterator(null);
	}
	
	public TreeIterator iterator(final TreeIterator t)
	{
		return new TreeIterator() {
		
			Tree active;
			TreeIterator curr;
			Iterator<Tree> level = children.iterator();
			Iterator<Tree> up = t;
			
			@Override
			public void remove() {
				level.remove();
				active.parent.children.remove(active);
			}
			
			@Override
			public Tree next() {
				if (level.hasNext()) {
						try {
						active = level.next();
						return active;
						} catch (Exception e ) {
							System.out.println(e.getMessage());
							e.printStackTrace();
						}
				}
				if (up != null) {
					curr = curr.up;
					active = curr.next();
					return active;
				}
				return null;
			}
			
			@Override
			public boolean hasNext() {
				return level.hasNext();
			}
			
			@Override
			public Tree nextLower() {
				level = active.children.iterator();
				active =  level.next();
				curr = active.iterator(this);
				return active;
			}
			
			@Override
			public boolean hasNextLower() {
				return (active.children.size() != 0);

			}

			@Override
			public int children() {
				return active.children.size();
			}

		};
	}
	
		
}
